﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using GameSchoolApplication.Models;
using GameSchoolApplication.Models.ViewModels;
using GameSchoolApplication;

namespace GameSchoolApplication.Repositories
{
    public class CourseRepository
    {
        gsDBDataContext link = new gsDBDataContext();

        /// <summary>
        /// 
        /// Precondition: A course has been created and has an ID
        /// Postcondition: The selected course is returned
        /// Author: Bjarmi mod. by Alma
        /// Date: 04.05. 2012
        /// </summary>
        public Course getCourseByID(int courseID)
        {
            Course selectedCourse = (from k in link.Courses
                               where k.cID == courseID
                               select k).First();            
            return selectedCourse; 
        }

        /// <summary>
        /// Gets a course based on email
        /// Precondition: course must exist
        /// Postcondition: A course has been returned
        /// Author: Bjarmi mod. by Alma
        /// Date: 04.05.2012
        /// </summary>
        public Course getCourseByName(string courseName)
        {
            Course myCourse = (from k in link.Courses
                                where k.name == courseName
                                select k).First();

            return myCourse;
        }

        /// <summary>
        /// Gets a list of all courses the given student is enrolled in.
        /// Author: Bjarmi
        /// Date: 05.05.2012
        /// </summary>
        /// <param name="studentID"></param>
        public IQueryable<Course> getCourseListForStudent(string studentID)
        {
            //selects all the courses, then cross references them with the StudentInClasses where 
            var result = (from c in link.Courses
                          from SiC in link.StudentInClasses
                          where c.cID == SiC.cID && SiC.stID == studentID
                          select c);

            return result;
        }

        /// <summary>
        /// Get a list of all courses
        /// Precondition: Courses have been registered
        /// Postcondition: A list of courses is returned
        /// Author: Bjarmi/Aron mod. by Alma
        /// Date: 04.05. 2012
        /// </summary>
        public IQueryable<Course> getAllCourses()
        {
            return link.Courses;
        }

        /// <summary>
        /// Adding a new course
        /// Precondition: The user is an administrator
        /// Postcondition: An admin has added a new course
        /// Author: Bjarmi/Aron mod. by Alma
        /// Date: 04.05. 2012
        /// </summary>
        public bool addCourse(Course ofCourse)
        {
            try
            {
                link.Courses.InsertOnSubmit(ofCourse);
            }
            catch (Exception)
            {
                return false;
            }
            return true; 
        }

        /// <summary>
        /// Removing a course
        /// Precondition: A course exists and the user is an admin
        /// Postcondition: The course has been deleted
        /// Author: Bjarmi mod. by Alma
        /// Date: 04.05. 2012
        /// </summary>
        public bool removeCourse(int courseID)
        {
            Course ofCourse = (from k in link.Courses
                               where k.cID == courseID
                               select k).First();
            if (ofCourse != null)
            {
                try
                {                    
                    link.Courses.DeleteOnSubmit(ofCourse);
                }
                catch (Exception)
                {
                    return false;
                }
                return true;
            }
            return false;
        }

        /// <summary>
        /// Editing a course
        /// Precondition: User must be an administrator/teacher and the course must exist
        /// Postcondition: Course information has been updated in the database
        /// Author: Aron mod. by Alma
        /// Date: 04.05. 2012
        /// </summary>
        public bool editCourse(Course ofCourse)
        {
            try
            {
                var myCourse = (from k in link.Courses
                            where k.cID == ofCourse.cID
                            select k).First();

                myCourse.name = ofCourse.name;
                myCourse.noSemester = ofCourse.noSemester;
                myCourse.noYear = ofCourse.noYear;
                myCourse.courseDesc = ofCourse.courseDesc;

                save();

                return true;
            }
            catch (Exception)
            {
                return false;
            }
            
        }

        /// <summary>
        /// Saves changes to database
        /// Precondition:
        /// Postcondition: Database has been updated
        /// Author: Aron og Bjarmi
        /// Date: 03.05.2012
        /// </summary>
        public void save()
        {
            link.SubmitChanges();
        }

        /// <summary>
        /// Returns a list of CourseIcons with the specified ID
        /// Precondition: ID must exist
        /// Postcondition: Database has been updated
        /// Author: Aron og Bjarmi
        /// Date: 03.05.2012
        /// </summary>
        public CourseIcon getCourseIcon(int courseID, string userID)
        {
            CourseIcon temp = new CourseIcon();
            temp.courseID = courseID;
            temp.courseName = (from c in link.Courses
                               where c.cID == courseID
                               select c.name).First();
            temp.maxLevel = Math.Max((from l in link.CourseLevels
                                      where l.cID == courseID
                                      select l).Count(), 1);
            temp.progress = (from l in link.CourseLevels
                             from f in link.UserFinishedLevels
                             where l.cID == courseID && l.lvlID == f.clID && f.userID == userID
                             select f).Count();

            return temp;
        }

        public bool addTeacherToCourse(TeachesClass teaches)
        {
            try
            {
                link.TeachesClasses.InsertOnSubmit(teaches);
                save(); 
            }
            catch(Exception)
            {
                return false; 
            }
            return true; 
        }

        public bool addStudentToCourse(AddUserToClassModel model)
        {
            StudentInClass s = new StudentInClass();
            s.cID = model.cID;
            s.stID = model.studentID;
            try
            {
                link.StudentInClasses.InsertOnSubmit(s);
                save(); 
            }
            catch
            {
                return false; 
            }
            return true; 
        }
    }
}